﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using HslCommunication.Enthernet.Redis;
using LongSCADA_WPF.Helpers;
using LongSCADA_WPF.Models;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LongSCADA_WPF.ViewModels
{
    public partial class ParamsViewModel : ObservableObject
    {
        [ObservableProperty]
        private RootParam _rootParam;

        private readonly GlobalHelper _globalHelper;
        private CancellationTokenSource _cts = new();
        public ParamsViewModel(IOptionsSnapshot<RootParam> optionsSnapshot,GlobalHelper globalHelper)
        {
            RootParam = optionsSnapshot.Value;
            _globalHelper = globalHelper;
        }

        [RelayCommand]
        void ToggleCollection()
        {
            if (RootParam.PlcParam.AutoCollect)
            {
                _globalHelper.StopReadData();
                _globalHelper.StartReadDataAsync();
            }
            else
            {
                //配置文件 - 默认非自动采集
                //注意：ToggleButton ->Unchecked
                _globalHelper.StopReadData();
            }
        }


        [RelayCommand]
        void ToggleMock()
        {
            if (RootParam.PlcParam.AutoMock)
            {
                StartMockData();
            }
            else
            {
                StopMockData();
            }
        }

        private void StartMockData()
        {
            _cts = new CancellationTokenSource();
            Task.Run(async () =>
            {
                ScadaReadData scadaReadData = new ScadaReadData();
                await WhiteRandom();
            }, _cts.Token);
        }

        private async Task WhiteRandom()
        {
            //通过反射获取Bool类型类型
            IEnumerable<PropertyInfo> propertiesBool = typeof(ScadaReadData).GetProperties()
            .Where(p => p.PropertyType == typeof(bool));

            //通过反射获取浮点类型类型
            IEnumerable<PropertyInfo> propertiesFloat = typeof(ScadaReadData).GetProperties()
            .Where(p => p.PropertyType == typeof(float));

            while (!_cts.Token.IsCancellationRequested)
            {
                Random random = new Random();
                foreach (var property in propertiesBool)
                {
                    
                    string? address = _globalHelper.ReadEntityList.FirstOrDefault
                    (x => x.En == property.Name)?.Address;

                    if (random.Next(0,3)!=0)
                    {
                        await _globalHelper.Plc.WriteAsync(address, true);
                    }
                    else
                    {
                        await _globalHelper.Plc.WriteAsync(address, false);
                    }
                }

                foreach (var property in propertiesFloat)
                {
                    float value = (float)(random.NextDouble() * 20 + 2);
                    string? address = _globalHelper.ReadEntityList.FirstOrDefault
                    (x => x.En == property.Name)?.Address;

                    if (!string.IsNullOrEmpty(address))
                    {
                        await _globalHelper.Plc.WriteAsync(address, value);
                    }
                }
                await Task.Delay(2000);
            }
        }
        private void StopMockData()
        {
            if (_cts!=null)
            {
                _cts.Cancel();
                _cts.Dispose();
            }
        }
    }
}
